package org.spiderflow.common.concurrent;

import java.util.concurrent.Future;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * @author zsh
 */
public class SpiderFlowThreadPoolExecutor {

    /**
     * 最大线程数
     */
    private final int maxThreads;

    /**
     * 真正线程池
     */
    private final ThreadPoolExecutor executor;

    /**
     * 线程number计数器
     */
    private final AtomicInteger poolNumber = new AtomicInteger(1);

    /**
     * 线程名称前缀
     */
    private static final String THREAD_POOL_NAME_PREFIX = "spider-flow-";
    private static final String GROUP_NAME = "spider-flow-group";

    public SpiderFlowThreadPoolExecutor(int maxThreads) {
        super();
        this.maxThreads = maxThreads;
        //创建线程池实例
        this.executor = new ThreadPoolExecutor(maxThreads, maxThreads, 10, TimeUnit.MILLISECONDS,
                new LinkedBlockingQueue<>(),
                runnable -> new Thread(new ThreadGroup(GROUP_NAME), runnable,
                        THREAD_POOL_NAME_PREFIX + poolNumber.getAndIncrement()));
    }

    public <T> Future<T> submit(Runnable runnable, T result) {
        return this.executor.submit(runnable, result);
    }

    public void execute(Runnable runnable) {
        this.executor.submit(runnable);
    }


    /**
     * 创建子线程池
     *
     * @param threads 线程池大小
     * @return
     */
    public SubThreadPoolExecutor createSubThreadPoolExecutor(int threads, ThreadSubmitStrategy submitStrategy) {
        return new SubThreadPoolExecutor(Math.min(maxThreads, threads), submitStrategy, executor, GROUP_NAME);
    }

}
